#include "signal_client.h"
#include <QJsonDocument>
#include <windows.h>
#include <Lmcons.h>
#include "easylog.h"

SignalClient::SignalClient(const QUrl &url, bool debug, QObject *parent):
    QObject(parent),
    m_url(url),
    m_debug(debug),
    m_connected(false)
{
    qDebug() << "WebSocket server:" << url;
    connect(&m_webSocket, &QWebSocket::connected, this, &SignalClient::onConnected);
    connect(&m_webSocket, &QWebSocket::disconnected, this, &SignalClient::onUnConnected);
    m_webSocket.open(QUrl(url));
    connect(&m_timer,SIGNAL(timeout()),this,SLOT(onReconenectTimeout()));
    m_timer.stop();
    m_timer.setSingleShot(false);
}

SignalClient::~SignalClient()
{
    m_timer.stop();
    m_webSocket.close();
}

void SignalClient::SendLogin()
{
    TCHAR username[UNLEN + 1];
    DWORD size = UNLEN + 1;
    GetUserName((TCHAR*)username, &size);

    QJsonObject obj;
    QJsonObject data;
    QJsonDocument doc;

    obj.insert("type",1000);
    data.insert("name",QString::fromWCharArray(username));
    obj.insert("data",data);
    m_peer_name = QString::fromWCharArray(username);
    m_webSocket.sendTextMessage(QJsonDocument(obj).toJson());
    gLog()->Log((QString::asprintf("%s %d",__FILE__,__LINE__) +"  send:\r\n" +
              QString(QJsonDocument(obj).toJson())).toStdString());

}

#define REQ_INROOM 1001
void SignalClient::SendInRoom(QString room)
{
    QJsonObject obj;
    QJsonObject data;
    data.insert("name",m_peer_name);
    data.insert("room_name",room);

    obj.insert("type",REQ_INROOM);
    obj.insert("data",data);
    m_webSocket.sendTextMessage(QString(QJsonDocument(obj).toJson()));
    gLog()->Log((QString::asprintf("%s %d",__FILE__,__LINE__) +"  send:\r\n" +
              QString(QJsonDocument(obj).toJson())).toStdString());
}

#define REQ_INROOM 1004
void SignalClient::SendListRoom(QString room)
{
    QJsonObject obj;
    QJsonObject data;
    data.insert("room_name",room);

    obj.insert("type",REQ_INROOM);
    obj.insert("data",data);
    m_webSocket.sendTextMessage(QString(QJsonDocument(obj).toJson()));
    gLog()->Log((QString::asprintf("%s %d",__FILE__,__LINE__) +"  send:\r\n" +
              QString(QJsonDocument(obj).toJson())).toStdString());
}

bool SignalClient::Connected()
{
    return m_connected;
}

void SignalClient::SetURL(QString url)
{
    m_url = url;
}

#define REQ_SDP 1005
void SignalClient::SendSDPOffer(QString peer, QString sdp)
{
    QJsonObject obj;
    QJsonObject data;
    data.insert("sdp",sdp);
    data.insert("name",m_peer_name);
    data.insert("remote_name",peer);
    obj.insert("type",REQ_SDP);
    obj.insert("data",data);
    qDebug()<<QString(QJsonDocument(obj).toJson());
    m_webSocket.sendTextMessage(QString(QJsonDocument(obj).toJson()));

    gLog()->Log((QString::asprintf("%s %d",__FILE__,__LINE__) +"  send:\r\n" +
              QString(QJsonDocument(obj).toJson())).toStdString());
}
#define REQ_CANDIDATE 1006
void SignalClient::SendICECandidate(QString peer, QString candidate)
{
    QJsonObject obj;
    QJsonObject data;
    data.insert("candidate",candidate);
    data.insert("name",m_peer_name);
    data.insert("remote_name",peer);
    obj.insert("type",REQ_CANDIDATE);
    obj.insert("data",data);
    qDebug()<<QString(QJsonDocument(obj).toJson());
    m_webSocket.sendTextMessage(QString(QJsonDocument(obj).toJson()));
    gLog()->Log((QString::asprintf("%s %d",__FILE__,__LINE__) +"  send:\r\n" +
              QString(QJsonDocument(obj).toJson())).toStdString());
}

QString SignalClient::PeerName()
{
    return m_peer_name;
}

void SignalClient::onConnected()
{
    qDebug() << "WebSocket connected";
    connect(&m_webSocket, &QWebSocket::textMessageReceived,
         this, &SignalClient::onTextMessageReceived);
    m_connected = true;
    m_timer.stop();
    connected();
    gLog()->Log((QString::asprintf("%s %d",__FILE__,__LINE__) +" +"
            " WebSocket connected").toStdString());
}

void SignalClient::onUnConnected()
{
    qDebug() <<"unconnected";
    m_timer.start(1000);
    m_timer.setSingleShot(false);
    m_webSocket.open(QUrl(m_url));
    closed();
    gLog()->Log((QString::asprintf("%s %d",__FILE__,__LINE__) +
                 " WebSocket unconnected").toStdString());

}

void SignalClient::onTextMessageReceived(QString message)
{
    qDebug() << "Message received:" << message;
    auto obj = QJsonDocument::fromJson(message.toUtf8()).object();
    qDebug()<<obj["type"];
    response(obj["type"].toInt(),obj["data"].toObject());
    gLog()->Log((QString::asprintf("%s %d",__FILE__,__LINE__) + "  recv:\r\n" +
              QString(QJsonDocument(obj).toJson())).toStdString());
}

void SignalClient::onSocketError(QAbstractSocket::SocketError error)
{
    qDebug()<<error;
    gLog()->Log((QString::asprintf("%s %d",__FILE__,__LINE__)   +
                 " WebSocket unconnected").toStdString());
}

void SignalClient::onReconenectTimeout()
{
    qDebug()<<"timeout";
}

